﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PushBox.Core
{
    /// <summary>
    /// 地图
    /// </summary>
    public class Map
    {
        public int Width { get; set; }

        public int Height { get; set; }

        public string MapInfo { get; private set; }

        public Person Person { get; set; }

        public List<Wall> Walls { get; set; } = new List<Wall>();  //List<>泛型

        public List<Box> Boxes { get; set; } = new List<Box>();

        public List<Key> Keys { get; set; } = new List<Key>();

        public Map(string mapInfo)
        {
            int x = 0, y = 0;
            foreach (char c in mapInfo)
            {
                switch (c)
                {
                    case '#':
                        Wall wall = new Wall();
                        wall.X = x;
                        wall.Y = y;
                        wall.Map = this;
                        this.Walls.Add(wall);
                        break;
                    case '+':
                        Key key = new Key();
                        key.X = x;
                        key.Y = y;
                        key.Map = this;
                        this.Keys.Add(key);
                        break;
                    case '*':
                        Box box = new Box();
                        box.X = x;
                        box.Y = y;
                        box.Map = this;
                        this.Boxes.Add(box);
                        break;
                    case '@':
                        this.Person = new Person();
                        this.Person.X = x;
                        this.Person.Y = y;
                        this.Person.Map = this;
                        break;
                    case '\n':
                        y++;
                        this.Width = Math.Max(x, this.Width);
                        x = 0;
                        break;
                }
                x++;
            }
            this.Height = y;
        }

        //委托  -- 函数指针
        /// <summary>
        /// 绘制地图委托 类型定义
        /// </summary>
        public delegate void Draw(Map sender);

        /// <summary>
        /// 绘制地图的函数
        /// </summary>
        public Draw DoDraw { get; set; }

        public bool IsPassed()
        {
            foreach (Key key in Keys)
            {
                Position p = this.GetObject(key.X, key.Y);
                if (!(p is Box))
                {
                    return false;
                }
            }
            return true;
        }

        /// <summary>
        /// 获取地图上某个点有没有对象
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <returns>如果有，返回，如果没有，返回空</returns>
        public Position GetObject(int x, int y)
        {
            //for (int i = 0; i < Walls.Count; i++)
            //{
            //    Wall wall = Walls[i];
            //    if (wall.X == x && wall.Y == y) return wall;
            //}
            foreach (Wall wall in Walls)
            {
                if (wall.X == x && wall.Y == y) return wall;
            }
            foreach (Box box in Boxes)
            {
                if (box.X == x && box.Y == y) return box;
            }
            if (Person.X == x && Person.Y == y) return Person;
            foreach (Key key in Keys)
            {
                if (key.X == x && key.Y == y) return key;
            }
            return null;
            //Position p1 = new Wall();
            //Position p2 = new Box();
            //Position p3 = new Key();
            //Position p4 = new Person();
            //可以用子类实例化父类，因为子类元素永远比父类多
            //所以，以上函数可以用position作为返回类型
            //返回position的各子类
        }
    }
}
